package com.sky.orangehireserver.modules.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sky.orangehireserver.common.domain.Organization;
import com.sky.orangehireserver.common.domain.Users;
import com.sky.orangehireserver.common.service.OrganizationService;
import com.sky.orangehireserver.common.service.UsersService;
import com.sky.orangehireserver.enums.ResponseCodeEnum;
import com.sky.orangehireserver.enums.UserRoleEnum;
import com.sky.orangehireserver.exception.BizException;
import com.sky.orangehireserver.modules.admin.dto.EnterpriseUserCreateDTO;
import com.sky.orangehireserver.modules.admin.dto.EnterpriseUserPasswordResetDTO;
import com.sky.orangehireserver.modules.admin.dto.EnterpriseUserQueryDTO;
import com.sky.orangehireserver.modules.admin.dto.EnterpriseUserUpdateDTO;
import com.sky.orangehireserver.modules.admin.service.AdminEnterpriseUserService;
import com.sky.orangehireserver.modules.admin.vo.EnterpriseUserVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 超级管理员企业用户管理服务实现类
 * 
 * @author sky
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AdminEnterpriseUserServiceImpl implements AdminEnterpriseUserService {

    private final UsersService usersService;
    private final OrganizationService organizationService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public EnterpriseUserVO createEnterpriseUser(EnterpriseUserCreateDTO createDTO) {
        log.info("开始创建企业用户，用户邮箱：{}，所属企业ID：{}", createDTO.getEmail(), createDTO.getOrgId());
        
        // 检查企业是否存在
        Organization organization = organizationService.getById(createDTO.getOrgId());
        if (organization == null) {
            throw new BizException("ORGANIZATION_NOT_FOUND", "所属企业不存在");
        }
        
        // 检查企业是否为激活状态
        if (!"active".equals(organization.getStatus())) {
            throw new BizException("ORGANIZATION_INACTIVE", "所属企业未激活，无法创建用户");
        }
        
        // 检查邮箱是否已存在
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Users::getEmail, createDTO.getEmail());
        if (usersService.count(queryWrapper) > 0) {
            throw new BizException("EMAIL_EXISTS", "邮箱已存在");
        }
        
        // 验证角色是否为企业内部角色
        if (!UserRoleEnum.isEnterpriseUser(createDTO.getRole())) {
            throw new BizException("INVALID_ROLE", "只能创建企业管理员或企业HR用户");
        }
        
        // 加密密码
        String hashedPassword = BCrypt.hashpw(createDTO.getPassword());
        
        // 创建用户实体
        Users user = Users.builder()
                .orgId(createDTO.getOrgId())
                .name(createDTO.getName())
                .email(createDTO.getEmail())
                .passwordHash(hashedPassword)
                .role(createDTO.getRole())
                .status("active") // 新创建的用户默认为激活状态
                .avatar(createDTO.getAvatar())
                .createdAt(LocalDateTime.now())
                .updatedAt(LocalDateTime.now())
                .build();
        
        // 保存用户
        boolean saved = usersService.save(user);
        if (!saved) {
            throw new BizException(ResponseCodeEnum.SYSTEM_ERROR.getErrorCode(), "创建企业用户失败");
        }
        
        log.info("企业用户创建成功，用户ID：{}", user.getId());
        return convertToVO(user, organization);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public EnterpriseUserVO updateEnterpriseUser(EnterpriseUserUpdateDTO updateDTO) {
        log.info("开始更新企业用户信息，用户ID：{}", updateDTO.getId());
        
        // 检查用户是否存在
        Users existingUser = usersService.getById(updateDTO.getId());
        if (existingUser == null) {
            throw new BizException("USER_NOT_FOUND", "用户不存在");
        }
        
        // 检查是否为企业用户
        if (!UserRoleEnum.isEnterpriseUser(existingUser.getRole())) {
            throw new BizException("INVALID_USER_TYPE", "只能管理企业内部用户");
        }
        
        // 如果更新邮箱，检查新邮箱是否已被其他用户使用
        if (StrUtil.isNotBlank(updateDTO.getEmail()) && !updateDTO.getEmail().equals(existingUser.getEmail())) {
            LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Users::getEmail, updateDTO.getEmail())
                    .ne(Users::getId, updateDTO.getId());
            if (usersService.count(queryWrapper) > 0) {
                throw new BizException("EMAIL_EXISTS", "邮箱已存在");
            }
        }
        
        // 如果更新角色，验证新角色是否为企业内部角色
        if (StrUtil.isNotBlank(updateDTO.getRole()) && !UserRoleEnum.isEnterpriseUser(updateDTO.getRole())) {
            throw new BizException("INVALID_ROLE", "只能设置为企业管理员或企业HR角色");
        }
        
        // 更新用户信息（只更新非空字段）
        Users updateUser = new Users();
        updateUser.setId(updateDTO.getId());
        updateUser.setUpdatedAt(LocalDateTime.now());
        
        if (StrUtil.isNotBlank(updateDTO.getName())) {
            updateUser.setName(updateDTO.getName());
        }
        if (StrUtil.isNotBlank(updateDTO.getEmail())) {
            updateUser.setEmail(updateDTO.getEmail());
        }
        if (StrUtil.isNotBlank(updateDTO.getRole())) {
            updateUser.setRole(updateDTO.getRole());
        }
        if (StrUtil.isNotBlank(updateDTO.getStatus())) {
            updateUser.setStatus(updateDTO.getStatus());
        }
        if (StrUtil.isNotBlank(updateDTO.getAvatar())) {
            updateUser.setAvatar(updateDTO.getAvatar());
        }
        
        // 执行更新
        boolean updated = usersService.updateById(updateUser);
        if (!updated) {
            throw new BizException(ResponseCodeEnum.SYSTEM_ERROR.getErrorCode(), "更新企业用户信息失败");
        }
        
        // 返回更新后的用户信息
        Users updatedUser = usersService.getById(updateDTO.getId());
        Organization organization = organizationService.getById(updatedUser.getOrgId());
        
        log.info("企业用户信息更新成功，用户ID：{}", updateDTO.getId());
        return convertToVO(updatedUser, organization);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteEnterpriseUser(Long id) {
        log.info("开始删除企业用户，用户ID：{}", id);
        
        // 检查用户是否存在
        Users user = usersService.getById(id);
        if (user == null) {
            throw new BizException("USER_NOT_FOUND", "用户不存在");
        }
        
        // 检查是否为企业用户
        if (!UserRoleEnum.isEnterpriseUser(user.getRole())) {
            throw new BizException("INVALID_USER_TYPE", "只能删除企业内部用户");
        }
        
        // TODO: 检查用户是否还有相关的业务数据，如果有则不允许删除
        // 这里可以根据业务需求添加相关检查逻辑
        
        // 执行删除
        boolean deleted = usersService.removeById(id);
        if (!deleted) {
            throw new BizException(ResponseCodeEnum.SYSTEM_ERROR.getErrorCode(), "删除企业用户失败");
        }
        
        log.info("企业用户删除成功，用户ID：{}", id);
    }

    @Override
    public EnterpriseUserVO getEnterpriseUserById(Long id) {
        log.info("查询企业用户详情，用户ID：{}", id);
        
        Users user = usersService.getById(id);
        if (user == null) {
            throw new BizException("USER_NOT_FOUND", "用户不存在");
        }
        
        // 检查是否为企业用户
        if (!UserRoleEnum.isEnterpriseUser(user.getRole())) {
            throw new BizException("INVALID_USER_TYPE", "只能查询企业内部用户");
        }
        
        Organization organization = organizationService.getById(user.getOrgId());
        return convertToVO(user, organization);
    }

    @Override
    public IPage<EnterpriseUserVO> getEnterpriseUserPage(EnterpriseUserQueryDTO queryDTO) {
        log.info("分页查询企业用户列表，查询条件：{}", queryDTO);
        
        // 构建查询条件
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Users::getRole, UserRoleEnum.ADMIN.getCode(), UserRoleEnum.RECRUITER.getCode()) // 只查询企业内部用户
                .eq(queryDTO.getOrgId() != null, Users::getOrgId, queryDTO.getOrgId())
                .like(StrUtil.isNotBlank(queryDTO.getName()), Users::getName, queryDTO.getName())
                .like(StrUtil.isNotBlank(queryDTO.getEmail()), Users::getEmail, queryDTO.getEmail())
                .eq(StrUtil.isNotBlank(queryDTO.getRole()), Users::getRole, queryDTO.getRole())
                .eq(StrUtil.isNotBlank(queryDTO.getStatus()), Users::getStatus, queryDTO.getStatus())
                .orderByDesc(Users::getCreatedAt);
        
        // 分页查询
        Page<Users> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        IPage<Users> userPage = usersService.page(page, queryWrapper);
        
        // 获取企业信息映射
        List<Long> orgIds = userPage.getRecords().stream()
                .map(Users::getOrgId)
                .distinct()
                .collect(Collectors.toList());
        
        Map<Long, Organization> orgMap = organizationService.listByIds(orgIds).stream()
                .collect(Collectors.toMap(Organization::getId, org -> org));
        
        // 转换为VO
        IPage<EnterpriseUserVO> voPage = new Page<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal());
        List<EnterpriseUserVO> voList = userPage.getRecords().stream()
                .map(user -> convertToVO(user, orgMap.get(user.getOrgId())))
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        
        return voPage;
    }

    @Override
    public List<EnterpriseUserVO> getEnterpriseUsersByOrgId(Long orgId) {
        log.info("查询企业用户列表，企业ID：{}", orgId);
        
        // 检查企业是否存在
        Organization organization = organizationService.getById(orgId);
        if (organization == null) {
            throw new BizException("ORGANIZATION_NOT_FOUND", "企业不存在");
        }
        
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Users::getOrgId, orgId)
                .in(Users::getRole, UserRoleEnum.ADMIN.getCode(), UserRoleEnum.RECRUITER.getCode())
                .orderByDesc(Users::getCreatedAt);
        
        List<Users> users = usersService.list(queryWrapper);
        return users.stream()
                .map(user -> convertToVO(user, organization))
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void enableEnterpriseUser(Long id) {
        log.info("启用企业用户，用户ID：{}", id);
        updateEnterpriseUserStatus(id, "active");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disableEnterpriseUser(Long id) {
        log.info("禁用企业用户，用户ID：{}", id);
        updateEnterpriseUserStatus(id, "inactive");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetEnterpriseUserPassword(EnterpriseUserPasswordResetDTO resetDTO) {
        log.info("重置企业用户密码，用户ID：{}", resetDTO.getId());
        
        // 检查用户是否存在
        Users user = usersService.getById(resetDTO.getId());
        if (user == null) {
            throw new BizException("USER_NOT_FOUND", "用户不存在");
        }
        
        // 检查是否为企业用户
        if (!UserRoleEnum.isEnterpriseUser(user.getRole())) {
            throw new BizException("INVALID_USER_TYPE", "只能重置企业内部用户密码");
        }
        
        // 加密新密码
        String hashedPassword = BCrypt.hashpw(resetDTO.getNewPassword());
        
        // 更新密码
        Users updateUser = new Users();
        updateUser.setId(resetDTO.getId());
        updateUser.setPasswordHash(hashedPassword);
        updateUser.setUpdatedAt(LocalDateTime.now());
        
        boolean updated = usersService.updateById(updateUser);
        if (!updated) {
            throw new BizException(ResponseCodeEnum.SYSTEM_ERROR.getErrorCode(), "重置密码失败");
        }
        
        log.info("企业用户密码重置成功，用户ID：{}", resetDTO.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDeleteEnterpriseUsers(List<Long> ids) {
        log.info("批量删除企业用户，用户ID列表：{}", ids);
        
        if (ids == null || ids.isEmpty()) {
            throw new BizException(ResponseCodeEnum.PARAM_NOT_VALID.getErrorCode(), "用户ID列表不能为空");
        }
        
        // 检查所有用户是否都是企业用户
        List<Users> users = usersService.listByIds(ids);
        for (Users user : users) {
            if (!UserRoleEnum.isEnterpriseUser(user.getRole())) {
                throw new BizException("INVALID_USER_TYPE", "只能删除企业内部用户");
            }
        }
        
        // TODO: 检查用户是否还有相关的业务数据，如果有则不允许删除
        // 这里可以根据业务需求添加相关检查逻辑
        
        // 执行批量删除
        boolean deleted = usersService.removeByIds(ids);
        if (!deleted) {
            throw new BizException(ResponseCodeEnum.SYSTEM_ERROR.getErrorCode(), "批量删除企业用户失败");
        }
        
        log.info("批量删除企业用户成功，删除数量：{}", ids.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteEnterpriseUsersByOrgId(Long orgId) {
        log.info("删除企业下的所有用户，企业ID：{}", orgId);
        
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Users::getOrgId, orgId)
                .in(Users::getRole, UserRoleEnum.ADMIN.getCode(), UserRoleEnum.RECRUITER.getCode());
        
        boolean deleted = usersService.remove(queryWrapper);
        if (!deleted) {
            log.warn("删除企业用户失败或该企业下没有用户，企业ID：{}", orgId);
        } else {
            log.info("删除企业下的所有用户成功，企业ID：{}", orgId);
        }
    }

    /**
     * 更新企业用户状态
     * 
     * @param id 用户ID
     * @param status 状态
     */
    private void updateEnterpriseUserStatus(Long id, String status) {
        // 检查用户是否存在
        Users user = usersService.getById(id);
        if (user == null) {
            throw new BizException("USER_NOT_FOUND", "用户不存在");
        }
        
        // 检查是否为企业用户
        if (!UserRoleEnum.isEnterpriseUser(user.getRole())) {
            throw new BizException("INVALID_USER_TYPE", "只能管理企业内部用户");
        }
        
        // 更新状态
        Users updateUser = new Users();
        updateUser.setId(id);
        updateUser.setStatus(status);
        updateUser.setUpdatedAt(LocalDateTime.now());
        
        boolean updated = usersService.updateById(updateUser);
        if (!updated) {
            throw new BizException(ResponseCodeEnum.SYSTEM_ERROR.getErrorCode(), "更新用户状态失败");
        }
    }

    /**
     * 将Users实体转换为EnterpriseUserVO
     * 
     * @param user 用户实体
     * @param organization 企业实体
     * @return 企业用户VO
     */
    private EnterpriseUserVO convertToVO(Users user, Organization organization) {
        EnterpriseUserVO vo = BeanUtil.copyProperties(user, EnterpriseUserVO.class);
        
        // 设置企业信息
        if (organization != null) {
            vo.setOrgName(organization.getName());
        }
        
        // 设置角色名称
        UserRoleEnum roleEnum = UserRoleEnum.getByCode(user.getRole());
        if (roleEnum != null) {
            vo.setRoleName(roleEnum.getName());
        }
        
        return vo;
    }
}